package com.microservice.system.data;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.microservice.core.utils.BatchInsertUtil;
import com.microservice.model.system.*;
import com.microservice.system.mapper.UserMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserDataService extends ServiceImpl<UserMapper, User> {
    @Resource
    private UserRoleDataService userRoleService;
    @Resource
    private RolePermissionDataService rolePermissionService;
    @Resource
    private PermissionDataService permissionService;
    @Resource
    private RoleDataService roleService;
    @Resource
    private BatchInsertUtil batchInsertUtil;

    public List<Permission> getPermissionByUsername(String username) {
        User user = super.getOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, username), true);
        return this.getPermissionByUser(user);
    }

    public List<Permission> getPermissionByUserId(Integer userId) {
        User user = super.getById(userId);
        return this.getPermissionByUser(user);
    }

    public List<Permission> getPermissionByUser(User user) {
        List<Permission> permissions = new ArrayList<>();
        if (null != user) {
            List<UserRole> userRoles = userRoleService.list(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, user.getId()));
            if (CollectionUtils.isNotEmpty(userRoles)) {
                List<Integer> roleIds = new ArrayList<>();
                userRoles.forEach(userRole -> roleIds.add(userRole.getRoleId()));
                List<RolePermission> rolePermissions = rolePermissionService.list(Wrappers.<RolePermission>lambdaQuery().in(RolePermission::getRoleId, roleIds));
                if (CollectionUtils.isNotEmpty(rolePermissions)) {
                    List<Integer> permissionIds = new ArrayList<>();
                    rolePermissions.forEach(rolePermission -> permissionIds.add(rolePermission.getPermissionId()));
                    permissions = permissionService.list(Wrappers.<Permission>lambdaQuery().in(Permission::getId, permissionIds));
                }
            }
        }
        return permissions;
    }

    public List<Role> getRoleByUsername(String username) {
        User user = super.getOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, username), true);
        return this.getRoleByUser(user);
    }

    public List<Role> getRoleByUserId(Integer userId) {
        User user = super.getById(userId);
        return this.getRoleByUser(user);
    }

    public List<Role> getRoleByUser(User user) {
        List<Role> roles = new ArrayList<>();
        if (null != user) {
            List<UserRole> userRoles = userRoleService.list(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, user.getId()));
            if (CollectionUtils.isNotEmpty(userRoles)) {
                List<Integer> roleIds = new ArrayList<>();
                userRoles.forEach(userRole -> roleIds.add(userRole.getRoleId()));
                roles = roleService.listByIds(roleIds);
            }
        }
        return roles;
    }

    public User getUserByUsername(String username) {
        return super.getOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, username), true);
    }

    public List<User> getUserList() {
        return super.list();
    }

    public boolean addUser(User user) {
        return super.save(user);
    }

    public boolean batchAddUserByUtil(List<User> userList) {
        int count = batchInsertUtil.batchUpdateOrInsert(1000,userList, UserMapper.class, (item, mapper) -> mapper.insert(item));
        return count > 0;
    }

    public boolean batchAddUser(List<User> userList) {
        return super.saveBatch(userList);
    }

    public boolean deleteUser(Integer id) {
        return super.removeById(id);
    }

    public boolean batchDeleteUser(List<Integer> ids) {
        return super.removeBatchByIds(ids);
    }

    public boolean updateUser(User user) {
        return super.updateById(user);
    }

    public boolean batchUpdateUser(List<User> userList) {
        return super.updateBatchById(userList);
    }

}
